#include "CDayWishMgr.h"
#include "../mainctrl.h"
#include "../data/CPlayerOnlineData.h"
#include "MsgAct.pb.h"
#include "../common/CRandArray.h"
#include "../cmd/dataprepare.h"

//获取每日许愿信息
int CDayWishMgr::GetDayWishInfo(CPlayerDetailInfoEx1& stPlayerDetailEx1,
        MsgAnsDayWish& stAns)
{
    UpdateDayWishItem(stPlayerDetailEx1);

    CPlayerDayWish& stPlayerDayWish = stPlayerDetailEx1._stUserDayWish;

    char chTodayWishTimes = stPlayerDayWish._stWishTimes.Get(
            CMainCtrl::m_pstMain->m_iNow, 0);
    stAns.set_can_wish_num(DAY_WISH_MACRO_WISH_TIMES - chTodayWishTimes);

    int iIndex = 0;
    char chCharMask = 0;
    bool bFinishWishOne = false;
    bool bFinishWishTwo = false;

    for (int i = 0; i < stPlayerDayWish._astWishItem.Size(); ++i)
    {
        iIndex = FindConfig(stPlayerDayWish._astWishItem[i]._iItemID);
        if (iIndex < 0)
        {
            CT_ERROR(("role(%u) item id(%d) config empty!",
                stPlayerDetailEx1._uiGID,
                stPlayerDayWish._astWishItem[i]._iItemID));
            continue;
        }

        CDayWishCfgData& stCfgData = GetConfig(iIndex);

        MsgDayWishInfo* pstMsgDayWish = stAns.add_wish_info();
        if (!pstMsgDayWish){CT_ERROR(("MsgDayWishInfo Null!"));continue;}

	    MsgGridItemInfo* pstMsgGridItem = pstMsgDayWish->mutable_award();
        if (!pstMsgGridItem){CT_ERROR(("MsgGridItemInfo Null!"));continue;}

	    pstMsgGridItem->set_item_store_pos(i);
	    pstMsgGridItem->set_item_type(stCfgData.GetItemType());
	    pstMsgGridItem->set_item_config_id(stCfgData.GetItemID());
	    pstMsgGridItem->set_item_count(stCfgData.GetItemNum());

        //许愿物品序号 值域[1,5] 避免使用默认值0
	    pstMsgDayWish->set_item_index(i + 1);

#define MACRO_DAY_WISH_NO_WISH 0    //未许愿
#define MACRO_DAY_WISH_IN_WISH 1    //已许愿

        bFinishWishOne = false;
        bFinishWishTwo = false;

        chCharMask = (char)((char)0x1 << DAY_WISH_MACRO_BIT_SET_ONE);
        if ((stPlayerDayWish._astWishItem[i]._chMask & chCharMask))//注意只能判断0和非0两种情况
        {
            bFinishWishOne = true;
	        pstMsgDayWish->set_wish_status1(MACRO_DAY_WISH_IN_WISH);
        }
        else
        {
	        pstMsgDayWish->set_wish_status1(MACRO_DAY_WISH_NO_WISH);
        }

        chCharMask = (char)((char)0x1 << DAY_WISH_MACRO_BIT_SET_TWO);
        if ((stPlayerDayWish._astWishItem[i]._chMask & chCharMask))//注意只能判断0和非0两种情况
        {
            bFinishWishTwo = true;
	        pstMsgDayWish->set_wish_status2(MACRO_DAY_WISH_IN_WISH);
        }
        else
        {
	        pstMsgDayWish->set_wish_status2(MACRO_DAY_WISH_NO_WISH);
        }

#define MACRO_DAY_WISH_CAN_NOT 0    //未达到领取条件
#define MACRO_DAY_WISH_ALREADY 1    //已领取
#define MACRO_DAY_WISH_CAN_GET 2    //可领取

        chCharMask = (char)((char)0x1 << DAY_WISH_MACRO_BIT_SET_THR);
        if ((stPlayerDayWish._astWishItem[i]._chMask & chCharMask))//注意只能判断0和非0两种情况
        {
	        pstMsgDayWish->set_award_status(MACRO_DAY_WISH_ALREADY);
        }
        else
        {
            if (bFinishWishOne && bFinishWishTwo)
            {
	            pstMsgDayWish->set_award_status(MACRO_DAY_WISH_CAN_GET);
            }
            else
            {
	            pstMsgDayWish->set_award_status(MACRO_DAY_WISH_CAN_NOT);
            }
        }
    }

    return 0;
}

int CDayWishMgr::UpdateDayWishItem(CPlayerDetailInfoEx1& stPlayerDetailEx1)
{
    CPlayerDayWish& stPlayerDayWish = stPlayerDetailEx1._stUserDayWish;

    if (CTTimeUtils::IsSameDay(stPlayerDayWish._iLastUpdateTime,
            CMainCtrl::m_pstMain->m_iNow))
    {
        return 0;
    }

    CRandArray<int, MAX_DAY_WISH_CONFIG_COUNT> aiWishItemRand;
    aiWishItemRand.Clear();

    CTLib::CTArray<int, MAX_DAY_WISH_ITEM_COUNT> aiWishItemResult;
    aiWishItemResult.Clear();

    for (int i = 0; i < _stDayWishCfg.GetConfigSize(); ++i)
    {
        CDayWishCfgData& stCfgData = _stDayWishCfg.GetConfig(i);
        aiWishItemRand.AddOneItem(stCfgData.GetID());
    }

    aiWishItemRand.Random();//打乱次序

    bool bItemIDWillUpdate = true;
    for (int i = 0; i < aiWishItemRand.Size() &&
            aiWishItemResult.Size() < aiWishItemResult.GetCount(); ++i)
    {
        bItemIDWillUpdate = true;
        for (int j = 0; j < stPlayerDayWish._astWishItem.Size(); ++j)
        {
            if (aiWishItemRand[i] == stPlayerDayWish._astWishItem[j]._iItemID
                && !IsWishItemNeedUpdate(stPlayerDayWish._astWishItem[j]))
            {
                bItemIDWillUpdate = false;
                break;
            }
        }

        if (!bItemIDWillUpdate)
        {
            continue;
        }

        aiWishItemResult.AddOneItem(aiWishItemRand[i]);
    }

    if (stPlayerDayWish._astWishItem.Size() <
            stPlayerDayWish._astWishItem.GetCount())
    {
        CDayWishItem stDayWishItem;
        for (int i = 0; i < aiWishItemResult.Size() &&
                stPlayerDayWish._astWishItem.Size() <
                    stPlayerDayWish._astWishItem.GetCount(); ++i)
        {
            stDayWishItem.Clear();
            stDayWishItem._iItemID = aiWishItemResult[i];
            stPlayerDayWish._astWishItem.AddOneItem(stDayWishItem);
        }
    }
    else
    {
        int iResultIndex = 0;
        for (int i = 0; i < stPlayerDayWish._astWishItem.Size(); ++i)
        {
            if (IsWishItemNeedUpdate(stPlayerDayWish._astWishItem[i]))
            {
                if (iResultIndex < aiWishItemResult.Size())
                {
                    stPlayerDayWish._astWishItem[i].Clear();
                    stPlayerDayWish._astWishItem[i]._iItemID =
                        aiWishItemResult[iResultIndex];
                    ++iResultIndex;
                }
            }
        }
    }

    stPlayerDayWish._iLastUpdateTime = CMainCtrl::m_pstMain->m_iNow;

    //这个数据必须更新回DB 避免每次都随机 导致一天内数据显示不一样
    CVarObjectKey stKey;
    stKey.m_chDataType = DT_PLAYER_DETAIL_EX1_INFO;
    stKey.m_u64ID = stPlayerDetailEx1._uiGID;
    CMainCtrl::m_pstMain->UpdateData(stKey, stPlayerDetailEx1, VOP_UPDATE);

    return 0;
}

bool CDayWishMgr::IsWishItemNeedUpdate(CDayWishItem& stWishItem)
{
    char chCharMaskOne = 0;
    char chCharMaskTwo = 0;

    //物品已经领取 需要更新
    chCharMaskOne = (char)((char)0x1 << DAY_WISH_MACRO_BIT_SET_THR);
    if ((stWishItem._chMask & chCharMaskOne))//注意只能判断0和非0两种情况
    {
        return true;
    }

    //物品没有许愿 需要更新
    chCharMaskOne = (char)((char)0x1 << DAY_WISH_MACRO_BIT_SET_ONE);
    chCharMaskTwo = (char)((char)0x1 << DAY_WISH_MACRO_BIT_SET_TWO);
    if ((!(stWishItem._chMask & chCharMaskOne)) &&
        (!(stWishItem._chMask & chCharMaskTwo)))//注意只能判断0和非0两种情况
    {
        return true;
    }

    return false;
}

//每日许愿
int CDayWishMgr::PlayerWish(CPlayerDetailInfoEx1& stPlayerDetailEx1,
        MsgReqDayWish& stReq, MsgAnsDayWish& stAns)
{
    if (!stReq.has_item_index() || !stReq.has_wish_index())
    {
        CT_WARNING((""));
        return ERROR_DAY_WISH_REQUEST_DATA;
    }

    int iItemIndex = stReq.item_index();//许愿物品序号 值域[1,5]避免使用默认值0
    int iWishIndex = stReq.wish_index();//许愿标签序号 值域[1,2]避免使用默认值0

    CPlayerDayWish& stPlayerDayWish = stPlayerDetailEx1._stUserDayWish;

    if (iItemIndex <= 0 || iItemIndex > stPlayerDayWish._astWishItem.Size())
    {
        CT_WARNING(("Item Index(%d) Wish Item Size(%d)",
            iItemIndex,stPlayerDayWish._astWishItem.Size()));
        return ERROR_DAY_WISH_REQUEST_DATA;
    }

    if (DAY_WISH_MACRO_WISH_ICON_ONE != iWishIndex &&
        DAY_WISH_MACRO_WISH_ICON_TWO != iWishIndex)
    {
        CT_WARNING(("Wish Index(%d)",iWishIndex));
        return ERROR_DAY_WISH_REQUEST_DATA;
    }

    char chTodayWishTimes = stPlayerDayWish._stWishTimes.Get(
            CMainCtrl::m_pstMain->m_iNow, 0);
    if (chTodayWishTimes >= DAY_WISH_MACRO_WISH_TIMES)
    {
        return ERROR_DAY_WISH_WISH_TIMES_EMPTY;
    }

    UpdateDayWishItem(stPlayerDetailEx1);

    char chCharMask = 0;
    if (DAY_WISH_MACRO_WISH_ICON_ONE == iWishIndex)
    {
        chCharMask = (char)((char)0x1 << DAY_WISH_MACRO_BIT_SET_ONE);
    }
    else if (DAY_WISH_MACRO_WISH_ICON_TWO == iWishIndex)
    {
        chCharMask = (char)((char)0x1 << DAY_WISH_MACRO_BIT_SET_TWO);
    }

    //注意只能判断0和非0两种情况
    if ((stPlayerDayWish._astWishItem[iItemIndex - 1]._chMask & chCharMask))
    {
        return ERROR_DAY_WISH_ALREADY_WISH;
    }

    stPlayerDayWish._astWishItem[iItemIndex - 1]._chMask |= chCharMask;
    stPlayerDayWish._stWishTimes.Add(1, CMainCtrl::m_pstMain->m_iNow, 0);

    return GetDayWishInfo(stPlayerDetailEx1, stAns);
}

//领取奖励
int CDayWishMgr::GetAward(CPlayerDetailInfoEx1& stPlayerDetailEx1,
        CPlayerOnlineData& stPlayerOnline, MsgReqDayWish& stReq,
        MsgAnsDayWish& stAns)
{
    if (!stReq.has_item_index())
    {
        CT_WARNING((""));
        return ERROR_DAY_WISH_REQUEST_DATA;
    }

    int iRet = 0;
    int iIndex = 0;
    int iItemIndex = stReq.item_index();//许愿物品序号 值域[1,5]避免使用默认值0

    CPlayerDayWish& stPlayerDayWish = stPlayerDetailEx1._stUserDayWish;

    if (iItemIndex <= 0 || iItemIndex > stPlayerDayWish._astWishItem.Size())
    {
        CT_WARNING(("Item Index(%d) Wish Item Size(%d)",
            iItemIndex,stPlayerDayWish._astWishItem.Size()));
        return ERROR_DAY_WISH_REQUEST_DATA;
    }

    UpdateDayWishItem(stPlayerDetailEx1);

    iIndex = FindConfig(stPlayerDayWish._astWishItem[iItemIndex - 1]._iItemID);
    if (iIndex < 0)
    {
        CT_ERROR(("role(%u) item id(%d) config empty!",
            stPlayerDetailEx1._uiGID,
            stPlayerDayWish._astWishItem[iItemIndex - 1]._iItemID));
        return ERROR_DAY_WISH_CONFIG_DATA;
    }

    CDayWishCfgData& stCfgData = GetConfig(iIndex);

    char chCharMask = 0;
    bool bFinishWishOne = false;
    bool bFinishWishTwo = false;

    chCharMask = (char)((char)0x1 << DAY_WISH_MACRO_BIT_SET_ONE);
    if ((stPlayerDayWish._astWishItem[iItemIndex - 1]._chMask & chCharMask))
    //注意只能判断0和非0两种情况
    {
        bFinishWishOne = true;
    }

    chCharMask = (char)((char)0x1 << DAY_WISH_MACRO_BIT_SET_TWO);
    if ((stPlayerDayWish._astWishItem[iItemIndex - 1]._chMask & chCharMask))
    //注意只能判断0和非0两种情况
    {
        bFinishWishTwo = true;
    }

    if (!bFinishWishTwo || !bFinishWishTwo)
    {
        return ERROR_DAY_WISH_UNFIT_AWARD;
    }

    chCharMask = (char)((char)0x1 << DAY_WISH_MACRO_BIT_SET_THR);
    if ((stPlayerDayWish._astWishItem[iItemIndex - 1]._chMask & chCharMask))
    //注意只能判断0和非0两种情况
    {
        return ERROR_DAY_WISH_ALREADY_AWARD;
    }

    CDropItem stDropItem;
    stDropItem.DropItem(stCfgData.GetItemID(), stCfgData.GetItemType(),
        stCfgData.GetItemNum());

    if (CMainCtrl::m_pstMain->m_stItemMgr.CheckBagFull(
            stPlayerOnline._stUserStorage, stDropItem))
    {
        return ERROR_STORAGE_BAG_IS_FULL;
    }

    //设置已领取
    stPlayerDayWish._astWishItem[iItemIndex - 1]._chMask |= chCharMask;

    //发送物品
    stDropItem.SetOssModule(OSS_MODULE_DAY_WISH);
    iRet = CMainCtrl::m_pstMain->m_stItemMgr.DropItem(NULL,
        stPlayerDetailEx1._uiGID, stDropItem);
    CT_RETURN(iRet);

    return GetDayWishInfo(stPlayerDetailEx1, stAns);
}

int CDayWishMgr::NotifyAllOnlineUsers()
{
    int iRet = 0;

    MsgReqDayWish stReqTmp;

    const CTArray<unsigned int, MAX_PLAYER_ONLINE>& astAllUsers =
        CMainCtrl::m_pstMain->m_stPlayerOnline.GetAllOnlineUser();

    for (int i = 0; i < astAllUsers.Size(); ++i)
    {
        stReqTmp.set_gid(astAllUsers[i]);
        stReqTmp.set_req_type(CMD_DAY_WISH_SUB_NOTIFY_INFO);
        iRet = CMainCtrl::m_pstMain->SendInnerCmd(astAllUsers[i],
            ID_MAIN_DAY_WISH, stReqTmp, true);

        if (iRet)
        {
            CT_ERROR(("send role(%u) inner cmd(%d) error(%d)",astAllUsers[i],
                ID_MAIN_DAY_WISH,iRet));
        }
    }

    CMainCtrl::m_pstMain->FlushSendCache();

    return 0;
}

